#include "BlockList.h"

void BlockList::initialize(uint8_t *buff, int width, int height, int totalBlocks, int columnAndRowSize)
{
    _blockList.clear();
    initBlockList(totalBlocks, columnAndRowSize);
    devideIntoBlocks(buff, width, height, columnAndRowSize);
}

void BlockList::initBlockList(int totalBlocks, int columnAndRowSize)
{
    for(int i=0; i < totalBlocks; ++i) {
        Matrix m(columnAndRowSize);
        _blockList.push_back(m);
    }
}

void BlockList::devideIntoBlocks(uint8_t *buff, int width, int height, int columnAndRowSize)
{
    uint8_t* temp = new uint8_t[columnAndRowSize];

    int row=0;
    int col=0;

    it = _blockList.begin();

    while(row < height) {

        for(col=0; col < width; col+=columnAndRowSize)
        {
            for(int colOffset=col; colOffset < col+columnAndRowSize; colOffset++)
            {
                for(int rowOffSet = row; rowOffSet < row+columnAndRowSize; rowOffSet++)
                {
                    temp[rowOffSet-row] = buff[rowOffSet*width+colOffset];
                }
                (*it).addColumn(temp,colOffset%columnAndRowSize);
            }
            ++it;
        }

        row+=columnAndRowSize;
    }

	delete[] temp;
}

uint8_t* BlockList::mergeBlocks(int width, int height, int columnLength)
{
    uint8_t* frameData = new uint8_t[width*height];

    it = _blockList.begin();

    int row=0;
    int col=0;

    while(it != _blockList.end())
    {
        int i = 0;
        for(int rowOffset = row; rowOffset < row+columnLength; ++rowOffset){
            for(int colOffset = col; colOffset < col+columnLength; ++colOffset){
                frameData[rowOffset*width+colOffset] = (uint8_t)((*it).getRowMajorElement(i));
                ++i;
            }
        }

        if(col >= width-columnLength)
        {
            col = 0;
            row+=columnLength;
        }
        else
        {
            col+=columnLength;
        }
        ++it;
    }

    return frameData;
}

Matrix* BlockList::getBlockAtCoord(int x, int y, uint8_t* data, int width, int height, int columnLength)
{
	MatrixXd m(columnLength, columnLength);

    //double blockData[columnLength*columnLength];
    int k = 0;
    for(int i = x; i < x+columnLength; ++i)
    {
        for(int j = y; j < y+columnLength; ++j)
        {
            int e = j*width+i;
            m(k) = data[e];
            ++k;
        }
    }

	Matrix *block = new Matrix(columnLength, m);

    return block;
}
